package com.maozzi.common.util;

import com.alibaba.fastjson.JSON;
import com.maozzi.common.constant.ErrorCodeConstant;
import com.maozzi.common.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * HTTP工具类
 *
 * @author maozi
 */
@Slf4j
public class HttpUtil {

    /**
     * 默认字符集：utf-8
     */
    private final static Charset UTF8_CHARSET = StandardCharsets.UTF_8;

    /**
     * get请求
     *
     * @param url URL
     * @return 结果
     * @throws BizException 业务异常
     */
    public static String sendGet(String url, Map<String, String> headers, Map<String, String> params) {
        String str;
        HttpGet httpGet = new HttpGet();
        if (!CollectionUtils.isEmpty(headers)) {
            headers.forEach(httpGet::addHeader);
        }
        if (!CollectionUtils.isEmpty(params)) {
            List<String> list = params.entrySet()
                    .stream()
                    .map(entry -> {
                        try {
                            String paramVal = URLEncoder.encode(entry.getValue(), UTF8_CHARSET.name());
                            return String.format("%s=%s", entry.getKey(), paramVal);
                        } catch (UnsupportedEncodingException e) {
                            throw new BizException(ErrorCodeConstant.FILED, e.getMessage(), e);
                        }
                    })
                    .collect(Collectors.toList());
            url = String.format("%s?%s", url, String.join("&", list));
        }
        httpGet.setURI(URI.create(url));
        try (CloseableHttpClient httpClient = HttpClients.createDefault();
             CloseableHttpResponse response = httpClient.execute(httpGet)) {
            str = analyzeResponse(response);
        } catch (Exception e) {
            throw new BizException(ErrorCodeConstant.FILED, e.getMessage(), e);
        }
        return str;
    }

    /**
     * post请求
     *
     * @param url    url
     * @param params 参数
     * @return 结果
     */
    public static String sendPost(String url, Map<String, String> headers, Map<String, String> params, Boolean isContentTypeJson) {
        String str;
        HttpPost httppost = new HttpPost(url);
        if (!CollectionUtils.isEmpty(headers)) {
            headers.forEach(httppost::addHeader);
        }
        HttpEntity entity;
        if (isContentTypeJson) {
            entity = new StringEntity(JSON.toJSONString(params), UTF8_CHARSET);
        } else {
            List<NameValuePair> list = params.entrySet()
                    .stream()
                    .map(entry -> new BasicNameValuePair(entry.getKey(), entry.getValue()))
                    .collect(Collectors.toList());
            entity = new UrlEncodedFormEntity(list, UTF8_CHARSET);
        }
        httppost.setEntity(entity);
        try (CloseableHttpClient httpClient = HttpClients.createDefault();
             CloseableHttpResponse response = httpClient.execute(httppost)) {
            str = analyzeResponse(response);
        } catch (IOException e) {
            throw new BizException(ErrorCodeConstant.FILED, e.getMessage(), e);
        }
        return str;
    }

    /**
     * @param response 请求结果
     * @return 返回
     * @throws IOException io 异常
     */
    private static String analyzeResponse(CloseableHttpResponse response) throws IOException {
        if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode()) {
            HttpEntity entity = response.getEntity();
            if (!ObjectUtils.isEmpty(entity)) {
                return EntityUtils.toString(entity, UTF8_CHARSET);
            }
        }
        return null;
    }
}